package com.vegetable.modules.service.finance.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.vegetable.common.utils.R;
import com.vegetable.modules.entity.baseData.AddressBook;
import com.vegetable.modules.entity.baseData.BankCard;
import com.vegetable.modules.entity.baseData.FundAccount;
import com.vegetable.modules.entity.finance.PaymentAccountRelease;
import com.vegetable.modules.entity.finance.PaymentLog;
import com.vegetable.modules.entity.finance.PaymentPurchase;
import com.vegetable.modules.entity.finance.PaymentPurchaseDetail;
import com.vegetable.modules.entity.finance.dto.PaymentApprovalDTO;
import com.vegetable.modules.entity.inbound.AgentDelivery;
import com.vegetable.modules.entity.wx.WXApproval;
import com.vegetable.modules.mapper.finance.PaymentPurchaseMapper;
import com.vegetable.modules.service.baseData.IAddressBookService;
import com.vegetable.modules.service.baseData.IBankCardService;
import com.vegetable.modules.service.baseData.IFundAccountService;
import com.vegetable.modules.service.finance.IPaymentLogService;
import com.vegetable.modules.service.finance.IPaymentPurchaseDetailService;
import com.vegetable.modules.service.finance.IPaymentPurchaseService;
import com.vegetable.modules.service.finance.PaymentApprovalService;
import com.vegetable.modules.service.finance.UnionPayService;
import com.vegetable.modules.service.finance.config.PaymentProcessConfig;
import com.vegetable.modules.service.inbound.IAgentDeliveryService;
import com.vegetable.modules.service.wx.WxCpMessageService;
import com.vegetable.modules.service.wx.WXApprovalService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.oa.WxCpApprovalDetailResult;
import me.chanjar.weixin.cp.bean.oa.WxCpOaApplyEventRequest;
import me.chanjar.weixin.cp.bean.oa.WxCpSpStatus;
import me.chanjar.weixin.cp.bean.oa.applydata.ApplyDataContent;
import me.chanjar.weixin.cp.bean.oa.applydata.ContentValue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 付款审批服务实现类
 *
 * @author Qoder
 */
@Slf4j
@Service
public class PaymentApprovalServiceImpl implements PaymentApprovalService {

    @Autowired
    private IPaymentPurchaseService paymentPurchaseService;

    @Autowired
    private IPaymentPurchaseDetailService paymentPurchaseDetailService;

    @Autowired
    private PaymentPurchaseMapper paymentPurchaseMapper;

    @Autowired
    private WxCpService wxCpService;

    @Autowired
    private WxCpMessageService wxCpMessageService;

    @Autowired
    private UnionPayService unionPayService;
    
    @Autowired
    private WXApprovalService wxApprovalService;
    
    @Autowired
    private IFundAccountService fundAccountService;
    
    @Autowired
    private IAddressBookService addressBookService;
    
    @Autowired
    private IBankCardService bankCardService;
    
    // 添加AgentDeliveryService依赖
    @Autowired
    private IAgentDeliveryService agentDeliveryService;

    @Value("${wechat.cp.appConfig.agentId}")
    private Integer agentId;
    
    @Value("${wechat.cp.corpId}")
    private String corpId;
    
    @Value("${wechat.cp.appConfig.secret}")
    private String corpSecret;
    
    @Value("${wechat.cp.admin.userIds:XiaoQin18754420999}")
    private String adminUserIds;
    
    @Autowired
    private com.vegetable.modules.service.wx.config.WxApprovalConfig wxApprovalConfig;
    
    @Autowired
    private com.vegetable.modules.service.finance.config.PaymentProcessConfig paymentProcessConfig;

    @Transactional
    @Override
    public R submitPaymentApproval(Long paymentId) {
        // 调用新的重载方法，传入null作为approvalDTO
        return submitPaymentApproval(paymentId, null);
    }
    
    @Transactional
    @Override
    public R submitPaymentApproval(Long paymentId, PaymentApprovalDTO approvalDTO) {
        try {
            // 获取付款详情
            R detailResult = paymentPurchaseService.detailPurchase(paymentId);
            if (detailResult.getCode() != 200) {
                return R.fail("获取付款详情失败: " + detailResult.getMsg());
            }

            PaymentPurchase payment = (PaymentPurchase) detailResult.getData();

            // 检查付款状态
            if (payment.getState() != 0) {
                return R.fail("付款状态不正确，当前状态: " + payment.getState());
            }

            // 如果approvalDTO为null，创建一个新的实例
            if (approvalDTO == null) {
                approvalDTO = new PaymentApprovalDTO();
            }

            // 验证收款人信息是否完整（必填项）
            if (approvalDTO.getPayeeName() == null || approvalDTO.getPayeeName().isEmpty()) {
                return R.fail("收款人全称不能为空");
            }
            
            if (approvalDTO.getPayeeBankAccount() == null || approvalDTO.getPayeeBankAccount().isEmpty()) {
                return R.fail("收款人银行账号不能为空");
            }
            
            if (approvalDTO.getPayeeBankName() == null || approvalDTO.getPayeeBankName().isEmpty()) {
                return R.fail("收款人开户行不能为空");
            }

            // 验证银行账号是否在addressBook中存在
            R validateResult = validateBankAccount(payment.getCustomerId(), approvalDTO.getPayeeBankAccount());
            if (validateResult.getCode() != 200) {
                return validateResult;
            }

            // 构建审批内容
            String approvalContent = buildApprovalContent(payment);

            // 提交企业微信审批
            String spNo = submitWxApproval(payment, approvalContent, approvalDTO);

            if (spNo != null) {
                // 更新付款记录的审批状态为审批中
                payment.setApprovalState(1); // 1表示审批中
                paymentPurchaseMapper.updateById(payment);

                return R.success("付款审批已提交，审批编号: " + spNo);
            } else {
                return R.fail("提交企业微信审批失败");
            }
        } catch (Exception e) {
            log.error("提交付款审批时发生异常", e);
            return R.fail("提交付款审批失败: " + e.getMessage());
        }
    }

    @Override
    public R handleWxApprovalResult(PaymentApprovalDTO approvalDTO) {
        try {
            Long paymentId = approvalDTO.getPaymentId();
            // 获取付款详情
            PaymentPurchase payment = paymentPurchaseMapper.selectById(paymentId);

            if (payment == null) {
                return R.fail("付款记录不存在");
            }

            // 检查付款审批状态
            if (payment.getApprovalState() == null || payment.getApprovalState() != 1) {
                return R.fail("付款审批状态不正确，当前审批状态: " + payment.getApprovalState());
            }

            // 检查是否启用自动支付
            if (paymentProcessConfig.isAutoExecutePayment()) {
                // 执行支付操作，传递收款人信息
                R payResult = unionPayService.executeSinglePayment(
                    payment, 
                    approvalDTO.getPayeeName(), 
                    approvalDTO.getPayeeBankAccount(), 
                    approvalDTO.getPayeeBankName()
                );
                
                if (payResult.getCode() == 0) {
                    // 支付成功，更新付款记录的状态为已支付
                    payment.setState(1); // 1表示实际已付
                    payment.setApprovalState(2); // 2表示审批通过
                    payment.setRemitTime(new Date()); // 设置打款时间
                    paymentPurchaseMapper.updateById(payment);
                    
                    // 查找关联的审批记录并同步状态到企业微信
                    try {
                        QueryWrapper<WXApproval> wrapper = new QueryWrapper<>();
                        wrapper.eq("payment_id", paymentId);
                        WXApproval wxApproval = wxApprovalService.getOne(wrapper);
                        
                        if (wxApproval != null) {
                            // 更新审批状态
                            wxApproval.setSpStatus("ALREADY_PAY");
                            wxApprovalService.updateById(wxApproval);
                            
                            // 同步状态到企业微信
                            boolean syncResult = wxApprovalService.syncApprovalStatusToWechat(wxApproval.getSpNo(), "ALREADY_PAY");
                            if (!syncResult) {
                                log.warn("同步审批状态到企业微信失败，审批编号: {}", wxApproval.getSpNo());
                            }
                        }
                    } catch (Exception e) {
                        log.warn("同步审批状态时发生异常", e);
                    }

                    return R.success("审批通过并支付成功");
                } else {
                    // 支付失败
                    payment.setApprovalState(2); // 2表示审批通过，但支付失败
                    paymentPurchaseMapper.updateById(payment);
                    
                    return R.fail("支付失败: " + payResult.getMsg());
                }
            } else {
                // 不自动执行支付，只更新审批状态
                payment.setApprovalState(2); // 2表示审批通过
                paymentPurchaseMapper.updateById(payment);

                return R.success("审批通过，等待手动执行支付");
            }
        } catch (Exception e) {
            log.error("处理企业微信审批结果时发生异常", e);
            return R.fail("处理审批结果失败: " + e.getMessage());
        }
    }
    
    @Override
    public R pullPaymentApprovalStatus(Long paymentId) {
        try {
            log.info("开始手动拉取付款单审批情况，付款ID: {}", paymentId);
            
            // 获取付款详情
            PaymentPurchase payment = paymentPurchaseMapper.selectById(paymentId);
            if (payment == null) {
                return R.fail("付款记录不存在");
            }
            
            // 检查付款是否有审批编号关联
            if (payment.getApprovalState() == null || payment.getApprovalState() == 0) {
                return R.fail("该付款记录尚未提交审批");
            }
            
            // 查找关联的审批记录
            QueryWrapper<WXApproval> wrapper = new QueryWrapper<>();
            wrapper.eq("payment_id", paymentId);
            List<WXApproval> wxApprovals = wxApprovalService.list(wrapper);
            
            if (wxApprovals.isEmpty()) {
                return R.fail("未找到关联的审批记录");
            }
            
            // 获取最新的审批记录
            WXApproval latestApproval = wxApprovals.get(0);
            for (WXApproval approval : wxApprovals) {
                if (approval.getCreateTime().after(latestApproval.getCreateTime())) {
                    latestApproval = approval;
                }
            }
            
            String spNo = latestApproval.getSpNo();
            if (spNo == null || spNo.isEmpty()) {
                return R.fail("审批记录缺少审批编号");
            }
            
            log.info("开始从企业微信获取审批详情，审批编号: {}", spNo);
            
            // 从企业微信获取最新的审批详情
            WxCpApprovalDetailResult detailResult = wxCpService.getOaService().getApprovalDetail(spNo);
            
            if (detailResult == null || detailResult.getErrCode() != 0) {
                log.error("获取审批详情失败，审批编号: {}, 错误码: {}, 错误信息: {}", 
                    spNo, 
                    detailResult != null ? detailResult.getErrCode() : "null",
                    detailResult != null ? detailResult.getErrMsg() : "null");
                return R.fail("获取审批详情失败: " + (detailResult != null ? detailResult.getErrMsg() : "未知错误"));
            }
            
            // 获取审批信息
            WxCpApprovalDetailResult.WxCpApprovalDetail approvalInfo = detailResult.getInfo();
            WxCpSpStatus spStatus = approvalInfo.getSpStatus();
            String spStatusName = spStatus.name(); // 获取枚举名称，如 "AUDITING", "PASSED" 等
            
            log.info("获取到审批详情，审批编号: {}, 审批状态: {}", spNo, spStatusName);
            
            // 更新本地审批记录
            latestApproval.setSpStatus(spStatusName);
            latestApproval.setSpComment(JSON.toJSONString(detailResult));
            latestApproval.setUpdateTime(new Date());
            wxApprovalService.updateById(latestApproval);
            
            // 根据审批状态更新付款记录
            String resultMsg = "";
            switch (spStatus) {
                case AUDITING: // 审批中
                    payment.setApprovalState(1); // 审批中
                    paymentPurchaseMapper.updateById(payment);
                    resultMsg = "审批状态: 审批中";
                    break;
                    
                case PASSED: // 已通过
                    // 检查是否启用自动支付
                    if (paymentProcessConfig.isAutoExecutePayment()) {
                        // 从审批记录中获取收款人信息
                        String payeeName = payment.getCustomerName();
                        String payeeBankAccount = "";
                        String payeeBankName = "";
                        
                        // 尝试从审批记录中获取收款人信息
                        try {
                            // 使用工具类提取收款人信息
                            Map<String, String> payeeInfo = WxApprovalPayeeInfoExtractor.extractPayeeInfo(approvalInfo);
                            payeeName = payeeInfo.get("payeeName");
                            payeeBankAccount = payeeInfo.get("payeeBankAccount");
                            payeeBankName = payeeInfo.get("payeeBankName");
                        } catch (Exception e) {
                            log.warn("解析审批详情中的收款人信息时发生异常", e);
                        }
                        
                        // 执行支付操作，传递收款人信息
                        R payResult = unionPayService.executeSinglePayment(
                            payment, 
                            payeeName, 
                            payeeBankAccount, 
                            payeeBankName
                        );
                        
                        if (payResult.getCode() == 0) {
                            // 支付成功
                            payment.setState(1); // 1表示实际已付
                            payment.setApprovalState(2); // 2表示审批通过
                            payment.setRemitTime(new Date()); // 设置打款时间
                            paymentPurchaseMapper.updateById(payment);
                            
                            // 更新审批状态并同步到企业微信
                            latestApproval.setSpStatus("ALREADY_PAY");
                            wxApprovalService.updateById(latestApproval);
                            
                            // 同步状态到企业微信
                            boolean syncResult = wxApprovalService.syncApprovalStatusToWechat(latestApproval.getSpNo(), "ALREADY_PAY");
                            if (!syncResult) {
                                log.warn("同步审批状态到企业微信失败，审批编号: {}", latestApproval.getSpNo());
                            }
                            
                            resultMsg = "审批已通过并支付成功";
                        } else {
                            // 支付失败
                            payment.setApprovalState(2); // 2表示审批通过，但支付失败
                            paymentPurchaseMapper.updateById(payment);
                            resultMsg = "审批已通过但支付失败: " + payResult.getMsg();
                        }
                    } else {
                        // 不自动执行支付，只更新审批状态
                        payment.setApprovalState(2); // 2表示审批通过
                        paymentPurchaseMapper.updateById(payment);
                        resultMsg = "审批已通过，等待手动执行支付";
                    }
                    break;
                    
                case REJECTED: // 已驳回
                    payment.setApprovalState(3); // 3表示审批拒绝
                    paymentPurchaseMapper.updateById(payment);
                    resultMsg = "审批已被驳回";
                    break;
                    
                case UNDONE: // 已撤销
                    payment.setApprovalState(0); // 0表示未提交审批
                    paymentPurchaseMapper.updateById(payment);
                    resultMsg = "审批已撤销";
                    break;
                    
                default:
                    resultMsg = "审批状态: " + spStatusName;
                    break;
            }
            
            log.info("手动拉取审批情况完成，付款ID: {}, 审批编号: {}, 结果: {}", paymentId, spNo, resultMsg);
            return R.success("拉取审批情况成功: " + resultMsg);
        } catch (WxErrorException e) {
            log.error("手动拉取付款单审批情况时发生微信异常，付款ID: {}", paymentId, e);
            return R.fail("拉取审批情况失败: " + e.getMessage());
        } catch (Exception e) {
            log.error("手动拉取付款单审批情况时发生异常，付款ID: {}", paymentId, e);
            return R.fail("拉取审批情况失败: " + e.getMessage());
        }
    }
    
    /**
     * 构建审批内容
     *
     * @param payment 付款信息
     * @return 审批内容
     */
    private String buildApprovalContent(PaymentPurchase payment) {
        StringBuilder content = new StringBuilder();
        content.append("付款申请\n");
        content.append("单据编号: ").append(payment.getDocNo()).append("\n");
        content.append("客户名称: ").append(payment.getCustomerName()).append("\n");
        content.append("付款金额: ").append(payment.getMoney()).append("元\n");
        content.append("付款时间: ").append(new SimpleDateFormat("yyyy-MM-dd").format(payment.getOrderTime())).append("\n");
        content.append("备注: ").append(payment.getRemark()).append("\n");

        // 添加付款明细
        content.append("付款明细:\n");
        QueryWrapper<PaymentPurchaseDetail> wrapper = new QueryWrapper<>();
        wrapper.eq("main_id", payment.getId());
        List<PaymentPurchaseDetail> details = paymentPurchaseDetailService.getBaseMapper().selectList(wrapper);

        for (int i = 0; i < details.size(); i++) {
            PaymentPurchaseDetail detail = details.get(i);
            content.append(i + 1).append(". ")
                    .append(detail.getCommodityNames())
                    .append(" - ")
                    .append(detail.getMoney()).append("元\n");
        }

        return content.toString();
    }

    /**
     * 提交企业微信审批
     *
     * @param payment 付款信息
     * @param content 审批内容
     * @param approvalDTO 审批信息（包含收款人信息）
     * @return 审批编号
     */
    private String submitWxApproval(PaymentPurchase payment, String content, PaymentApprovalDTO approvalDTO) {
        try {
            log.info("开始提交企业微信审批，付款ID: {}, 付款金额: {}", payment.getId(), payment.getMoney());
            
            // 构建审批请求，使用企业微信官方SDK的WxCpOaApplyEventRequest
            WxCpOaApplyEventRequest approvalRequest = new WxCpOaApplyEventRequest();
            approvalRequest.setCreatorUserId(wxApprovalConfig.getCreatorUserId()); // 使用配置文件中的创建者用户ID
            approvalRequest.setTemplateId(wxApprovalConfig.getTemplateId()); // 使用配置文件中的模板ID
            approvalRequest.setUseTemplateApprover(1); // 使用模板审批人，根据您的指示重新设计模板

            // 构建申请数据
            WxCpOaApplyEventRequest.ApplyData applyData = new WxCpOaApplyEventRequest.ApplyData();
            List<ApplyDataContent> contents = new ArrayList<>();

            // 添加付款事由 (必需控件)
            ApplyDataContent reasonContent = new ApplyDataContent();
            reasonContent.setControl("Textarea");
            ContentValue reasonValue = new ContentValue();
            reasonValue.setText(content);
            reasonContent.setValue(reasonValue);
            reasonContent.setId("item-1494251039326"); // 付款事由
            contents.add(reasonContent);

            // 添加付款金额 (必需控件)
            ApplyDataContent amountContent = new ApplyDataContent();
            amountContent.setControl("Money");
            ContentValue amountValue = new ContentValue();
            // 确保金额格式正确，使用BigDecimal避免精度问题，且只保留两位小数
            String moneyStr = "0.00";
            if (payment.getMoney() != null) {
                // 保留两位小数
                moneyStr = payment.getMoney().setScale(2, BigDecimal.ROUND_HALF_UP).toString();
            }
            amountValue.setNewMoney(moneyStr);
            amountContent.setValue(amountValue);
            amountContent.setId("item-1494251052639"); // 付款金额
            contents.add(amountContent);
            
            log.info("设置付款金额控件，控件ID: item-1494251052639, 金额值: {}", moneyStr);

            // 添加付款方式 (必需控件) - 默认选择银行卡
            ApplyDataContent methodContent = new ApplyDataContent();
            methodContent.setControl("Selector");
            ContentValue methodValue = new ContentValue();
            methodValue.setSelector(new ContentValue.Selector());
            methodValue.getSelector().setType("single");
            // 修复类型不兼容问题，使用选项键而不是字符串
            List<ContentValue.Selector.Option> options = new ArrayList<>();
            ContentValue.Selector.Option option = new ContentValue.Selector.Option();
            option.setKey("option-3742851564"); // 银行卡选项键
            options.add(option);
            methodValue.getSelector().setOptions(options);
            methodContent.setValue(methodValue);
            methodContent.setId("item-1494251058811"); // 付款方式
            contents.add(methodContent);

            // 添加付款日期 (必需控件) - 使用当前日期
            ApplyDataContent dateContent = new ApplyDataContent();
            dateContent.setControl("Date");
            ContentValue dateValue = new ContentValue();
            dateValue.setDate(new ContentValue.Date());
            // 修复方法名，使用正确的方法设置日期
            dateValue.getDate().setTimestamp(String.valueOf(System.currentTimeMillis() / 1000));
            dateContent.setValue(dateValue);
            dateContent.setId("item-1494251158679"); // 付款日期
            contents.add(dateContent);

            // 添加收款人全称 (必需控件) - 从参数中获取或从付款信息中获取
            ApplyDataContent payeeContent = new ApplyDataContent();
            payeeContent.setControl("Text");
            ContentValue payeeValue = new ContentValue();
            String payeeName = payment.getCustomerName();
            if (approvalDTO != null && approvalDTO.getPayeeName() != null && !approvalDTO.getPayeeName().isEmpty()) {
                payeeName = approvalDTO.getPayeeName();
            }
            payeeValue.setText(payeeName != null ? payeeName : "");
            payeeContent.setValue(payeeValue);
            payeeContent.setId("item-1494251166594"); // 收款人全称
            contents.add(payeeContent);

            // 添加银行账号 (必需控件) - 从参数中获取或从付款账户信息中获取
            ApplyDataContent accountContent = new ApplyDataContent();
            accountContent.setControl("Text");
            ContentValue accountValue = new ContentValue();
            String bankAccountNo = "";
            if (approvalDTO != null && approvalDTO.getPayeeBankAccount() != null && !approvalDTO.getPayeeBankAccount().isEmpty()) {
                bankAccountNo = approvalDTO.getPayeeBankAccount();
                log.info("使用前端传递的银行账号: {}", bankAccountNo);
            } else {
                // 获取实际的银行账号信息
                bankAccountNo = getBankAccountNo(payment);
                log.info("从系统获取银行账号: {}", bankAccountNo);
            }
            log.info("最终使用的银行账号: {}", bankAccountNo);
            accountValue.setText(bankAccountNo != null ? bankAccountNo : "");
            accountContent.setValue(accountValue);
            accountContent.setId("item-1494251179316"); // 银行账号
            contents.add(accountContent);

            // 添加开户行 (必需控件) - 从参数中获取或从付款账户信息中获取
            ApplyDataContent bankContent = new ApplyDataContent();
            bankContent.setControl("Text");
            ContentValue bankValue = new ContentValue();
            String bankName = "";
            if (approvalDTO != null && approvalDTO.getPayeeBankName() != null && !approvalDTO.getPayeeBankName().isEmpty()) {
                bankName = approvalDTO.getPayeeBankName();
                log.info("使用前端传递的开户行: {}", bankName);
            } else {
                // 获取实际的开户行信息
                bankName = getBankName(payment);
                log.info("从系统获取开户行: {}", bankName);
            }
            log.info("最终使用的开户行: {}", bankName);
            bankValue.setText(bankName != null ? bankName : "");
            bankContent.setValue(bankValue);
            bankContent.setId("item-1494251194643"); // 开户行
            contents.add(bankContent);

            // 获取代办交货信息并添加附件
            try {
                List<String> mediaIds = getAgentDeliveryAttachments(payment);
                if (!mediaIds.isEmpty()) {
                    // 添加附件信息到审批请求
                    // 使用File控件来添加附件
                    ApplyDataContent fileContent = new ApplyDataContent();
                    fileContent.setControl("File");
                    fileContent.setId("item-1494251220825"); // 设置一个合适的ID
                    
                    ContentValue fileValue = new ContentValue();
                    // 设置文件列表
                    List<ContentValue.File> files = new ArrayList<>();
                    for (String mediaId : mediaIds) {
                        ContentValue.File file = new ContentValue.File();
                        file.setFileId(mediaId);
                        file.setFileName("order_image.jpg"); // 设置文件名
                        files.add(file);
                    }
                    fileValue.setFiles(files);
                    fileContent.setValue(fileValue);
                    contents.add(fileContent);
                    log.info("添加了 {} 个附件到审批请求", mediaIds.size());
                }
            } catch (Exception e) {
                // 即使获取附件失败，也不影响审批申请的提交
                log.warn("获取代办交货附件时发生异常，但不影响审批申请提交", e);
            }

            applyData.setContents(contents);
            approvalRequest.setApplyData(applyData);

            log.info("提交企业微信审批请求: {}", JSON.toJSONString(approvalRequest));

            // 调用企业微信API提交审批
            String spNo = wxCpService.getOaService().apply(approvalRequest);
            
            if (spNo != null) {
                // 保存审批记录到数据库
                saveWXApprovalRecord(payment, spNo, content);
                return spNo;
            } else {
                log.error("提交企业微信审批失败，返回审批编号为空");
                return null;
            }
        } catch (Exception e) {
            log.error("提交企业微信审批失败", e);
            return null;
        }
    }
    
    /**
     * 获取代办交货附件
     *
     * @param payment 付款信息
     * @return 媒体ID列表
     */
    private List<String> getAgentDeliveryAttachments(PaymentPurchase payment) {
        List<String> mediaIds = new ArrayList<>();
        try {
            log.info("开始获取代办交货附件，付款ID: {}", payment.getId());
            
            // 获取付款明细
            QueryWrapper<PaymentPurchaseDetail> wrapper = new QueryWrapper<>();
            wrapper.eq("main_id", payment.getId());
            List<PaymentPurchaseDetail> details = paymentPurchaseDetailService.getBaseMapper().selectList(wrapper);
            
            log.info("获取到 {} 条付款明细", details.size());
            
            // 遍历付款明细，获取对应的代办交货信息
            for (PaymentPurchaseDetail detail : details) {
                Long orderId = detail.getOrderId();
                if (orderId != null) {
                    log.info("获取代办交货信息，订单ID: {}", orderId);
                    
                    // 获取代办交货信息
                    AgentDelivery agentDelivery = agentDeliveryService.getById(orderId);
                    if (agentDelivery != null) {
                        String orderImage = agentDelivery.getOrderImage();
                        log.info("代办交货订单图片链接: {}", orderImage);
                        
                        // 如果有订单图片链接，则上传到企业微信
                        if (orderImage != null && !orderImage.isEmpty()) {
                            try {
                                // 上传图片到企业微信并获取mediaId
                                String mediaId = uploadImageToWx(orderImage);
                                if (mediaId != null && !mediaId.isEmpty()) {
                                    mediaIds.add(mediaId);
                                    log.info("成功上传图片到企业微信，mediaId: {}", mediaId);
                                } else {
                                    log.warn("上传图片到企业微信失败，订单ID: {}", orderId);
                                }
                            } catch (Exception e) {
                                log.error("上传图片到企业微信时发生异常，订单ID: {}", orderId, e);
                            }
                        } else {
                            log.info("代办交货订单没有图片附件，订单ID: {}", orderId);
                        }
                    } else {
                        log.warn("未找到代办交货信息，订单ID: {}", orderId);
                    }
                }
            }
        } catch (Exception e) {
            log.error("获取代办交货附件时发生异常，付款ID: {}", payment.getId(), e);
        }
        
        log.info("总共获取到 {} 个附件", mediaIds.size());
        return mediaIds;
    }
    
    /**
     * 上传图片到企业微信
     *
     * @param imageUrl 图片URL
     * @return mediaId
     * @throws Exception 上传失败时抛出异常
     */
    private String uploadImageToWx(String imageUrl) throws Exception {
        log.info("开始上传图片到企业微信，图片URL: {}", imageUrl);
        
        try {
            // 从URL下载图片
            URL url = new URL(imageUrl);
            URLConnection connection = url.openConnection();
            connection.setRequestProperty("User-Agent", "Mozilla/5.0");
            InputStream inputStream = connection.getInputStream();
            
            // 根据URL获取文件名
            String fileName = "order_image.jpg"; // 默认文件名
            String path = url.getPath();
            if (path != null && path.lastIndexOf("/") != -1) {
                String urlFileName = path.substring(path.lastIndexOf("/") + 1);
                if (urlFileName != null && !urlFileName.isEmpty()) {
                    fileName = urlFileName;
                }
            }
            
            // 上传到企业微信
            WxMediaUploadResult uploadResult = wxCpService.getMediaService().upload("image", fileName, inputStream);
            
            if (uploadResult != null && uploadResult.getMediaId() != null) {
                log.info("图片上传成功，mediaId: {}", uploadResult.getMediaId());
                return uploadResult.getMediaId();
            } else {
                log.warn("图片上传失败，uploadResult: {}", uploadResult);
                return null;
            }
        } catch (WxErrorException e) {
            log.error("上传图片到企业微信时发生微信异常，图片URL: {}", imageUrl, e);
            throw e;
        } catch (Exception e) {
            log.error("上传图片到企业微信时发生异常，图片URL: {}", imageUrl, e);
            throw e;
        }
    }
    
    /**
     * 获取银行账号信息
     *
     * @param payment 付款信息
     * @return 银行账号
     */
    public String getBankAccountNo(PaymentPurchase payment) {
        try {
            log.info("开始获取银行账号信息，付款ID: {}", payment.getId());
            
            // 从付款账户信息中获取银行账号
            if (payment.getAccountReleases() != null && !payment.getAccountReleases().isEmpty()) {
                log.info("付款账户释放列表不为空，大小: {}", payment.getAccountReleases().size());
                PaymentAccountRelease accountRelease = payment.getAccountReleases().get(0);
                log.info("第一个账户释放信息: accountId={}, accountName={}", 
                    accountRelease.getAccountId(), accountRelease.getAccountName());
                
                if (accountRelease.getAccountId() != null) {
                    // 通过accountId关联到FundAccount获取账户信息
                    FundAccount fundAccount = fundAccountService.getById(accountRelease.getAccountId());
                    log.info("获取到的FundAccount信息: {}", fundAccount);
                    
                    if (fundAccount != null && fundAccount.getCardNo() != null) {
                        log.info("成功获取银行账号: {}", fundAccount.getCardNo());
                        return fundAccount.getCardNo();
                    } else {
                        log.warn("FundAccount或CardNo为空，fundAccount={}, cardNo={}", 
                            fundAccount, fundAccount != null ? fundAccount.getCardNo() : "N/A");
                    }
                } else {
                    log.warn("accountId为空");
                }
            } else {
                log.warn("付款账户释放列表为空或null");
            }
            
            // 如果没有找到，返回空字符串
            log.info("未能获取到银行账号，返回空字符串");
            return "";
        } catch (Exception e) {
            log.error("获取银行账号信息失败", e);
            return "";
        }
    }
    
    /**
     * 获取开户行信息
     *
     * @param payment 付款信息
     * @return 开户行名称
     */
    public String getBankName(PaymentPurchase payment) {
        try {
            log.info("开始获取开户行信息，付款ID: {}", payment.getId());
            
            // 从付款账户信息中获取开户行信息
            if (payment.getAccountReleases() != null && !payment.getAccountReleases().isEmpty()) {
                log.info("付款账户释放列表不为空，大小: {}", payment.getAccountReleases().size());
                PaymentAccountRelease accountRelease = payment.getAccountReleases().get(0);
                log.info("第一个账户释放信息: accountId={}, accountName={}", 
                    accountRelease.getAccountId(), accountRelease.getAccountName());
                
                if (accountRelease.getAccountName() != null && !accountRelease.getAccountName().isEmpty()) {
                    log.info("直接从accountRelease获取开户行: {}", accountRelease.getAccountName());
                    return accountRelease.getAccountName();
                }
                
                // 如果accountName为空，尝试从FundAccount获取
                if (accountRelease.getAccountId() != null) {
                    FundAccount fundAccount = fundAccountService.getById(accountRelease.getAccountId());
                    log.info("获取到的FundAccount信息: {}", fundAccount);
                    
                    if (fundAccount != null && fundAccount.getAccountName() != null) {
                        log.info("从FundAccount获取开户行: {}", fundAccount.getAccountName());
                        return fundAccount.getAccountName();
                    } else {
                        log.warn("FundAccount或AccountName为空，fundAccount={}, accountName={}", 
                            fundAccount, fundAccount != null ? fundAccount.getAccountName() : "N/A");
                    }
                } else {
                    log.warn("accountId为空");
                }
            } else {
                log.warn("付款账户释放列表为空或null");
            }
            
            // 如果没有找到，返回空字符串
            log.info("未能获取到开户行，返回空字符串");
            return "";
        } catch (Exception e) {
            log.error("获取开户行信息失败", e);
            return "";
        }
    }
    
    /**
     * 验证银行账号是否在BankCard中存在
     *
     * @param customerId 客户ID
     * @param bankAccount 银行账号
     * @return 验证结果
     */
    public R validateBankAccount(Long customerId, String bankAccount) {
        try {
            log.info("开始验证银行账号，客户ID: {}, 银行账号: {}", customerId, bankAccount);
            
            // 根据customerId获取该客户的所有银行卡
            List<BankCard> bankCards = bankCardService.listByAddressBookId(customerId);
            if (bankCards == null || bankCards.isEmpty()) {
                log.warn("客户银行账号信息为空，客户ID: {}", customerId);
                return R.fail("客户银行账号信息为空");
            }
            
            // 检查bankAccount是否在银行卡列表中
            boolean found = false;
            for (BankCard card : bankCards) {
                if (card.getBankNo() != null && card.getBankNo().trim().equals(bankAccount.trim())) {
                    found = true;
                    break;
                }
            }
            
            if (!found) {
                log.warn("银行账号不在客户银行账号列表中，客户ID: {}, 银行账号: {}", customerId, bankAccount);
                return R.fail("银行账号不在客户银行账号列表中");
            }
            
            log.info("银行账号验证通过，客户ID: {}, 银行账号: {}", customerId, bankAccount);
            return R.success("银行账号验证通过");
        } catch (Exception e) {
            log.error("验证银行账号时发生异常，客户ID: {}, 银行账号: {}", customerId, bankAccount, e);
            return R.fail("验证银行账号失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取企业微信access_token
     * 
     * @return access_token
     * @throws Exception 获取失败时抛出异常
     */
    private String getAccessToken() throws Exception {
        String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpId + "&corpsecret=" + corpSecret;
        String res = HttpUtil.get(url);
        JSONObject jsonObject = JSONObject.parseObject(res);
        String accessToken = null;
        if(CollectionUtil.isNotEmpty(jsonObject)){
            accessToken = jsonObject.getString("access_token");
        }
        if(StrUtil.isBlank(accessToken)){
            throw new Exception("ACCESS_TOKEN 获取失败");
        }
        return accessToken;
    }
    
    /**
     * 保存审批记录到数据库
     * 
     * @param payment 付款信息
     * @param spNo 审批编号
     * @param content 审批内容
     */
    private void saveWXApprovalRecord(PaymentPurchase payment, String spNo, String content) {
        try {
            WXApproval wxApproval = new WXApproval();
            wxApproval.setApprovalType(1); // 1表示付款审批
            wxApproval.setSpNo(spNo);
            wxApproval.setReimbursementType("付款审批");
            wxApproval.setSpStatus("AUDITING"); // AUDITING表示审批中
            // 使用配置文件中的创建者用户ID作为申请人ID
            wxApproval.setUserId(wxApprovalConfig.getCreatorUserId());
            // 使用配置文件中的创建者用户ID作为申请人姓名
            wxApproval.setUserName(wxApprovalConfig.getCreatorUserId());
            wxApproval.setApplyTime(new Date());
            wxApproval.setMoney(payment.getMoney());
            wxApproval.setApprovalContent(content);
            wxApproval.setSpComment("系统生成的付款审批");
            wxApproval.setCreateTime(new Date());
            wxApproval.setUpdateTime(new Date());
            wxApproval.setPaymentId(payment.getId()); // 关联付款ID
            
            // 保存到数据库
            wxApprovalService.save(wxApproval);
            
            log.info("保存审批记录到数据库，付款ID: {}, 审批编号: {}", payment.getId(), spNo);
        } catch (Exception e) {
            log.error("保存审批记录到数据库失败，付款ID: {}", payment.getId(), e);
        }
    }
}